import mitt from 'mitt'
import mqtt from 'mqtt/dist/mqtt.min.js'
import { ajhttp } from '@/utils/http'

let clientIns = null

const eventBus = mitt()

const topic = {
    response: '/mainapplicationresponse',
    request: '/mainapplication'
}

export const applicationConfig = {
    intelligenceCfg: {
        carIdentification: {},
        barrierGate: {},
        capture: {},
        ttsCfg: {},
        trafficLight: {},
        outdoorScreen: {},
        electronicFence: {},
        charge: {}
    },
    systemCfg: {
        instrument: {},
        weighting: {},
        pound: {},
        print: {},
        discount: {},
        dataSync: {},
        dataBackup: {},
        overload: {}
    },
    maintenanceCfg: {
        version: {}
    }
}

export enum MQTTEvent {
    Connect = 'Connect',
    Disconnect = 'Disconnect',
    Error = 'Error'
}

export const enum cmdKey {
    platformDataCorrect = 0,
    manualBackup = 1,
    manualRestore = 2,
    dbCleanAll = 3,
    dbCleanupByMonth = 4,
    zhenShiCamera = 5,
    controllerTool = 6,
    restartSystem = 7,
    updateSystem = 8,
    downloadDb = 9,
    getVzDevices = 10,
    updateVzDevice = 11,
    poundImage = 12,
    print = 13,
    openAllGate = 14
}

const defaultToken = 'MNMUMgYDf16vRPn5FRyDGhZpozqn6qbdX7r+DL4+XdeI5H2+YX9Pk/cg0Wy/yG1HutTH3hVBJhyHaBaozK66iOYMC93i81RdbHqC8F1ethYPPSkJ5lb4mqk0Awvw1EiW3aqpepQAAEKwlY8M9hWlSjSqGRUpMV2nXidsFdf28Fo='

const server = 'hqmqtt.tccxtwas.com:5001'
const mqttUrl = `wxs://${server}/mqtt`

const messageType = {
    getCfg: {
        callback: null,
        type: 0
    },
    updateCfg: {
        callback: null,
        type: 1
    },
    execCmd: {
        callback: null,
        type: 4,
        silent: false
    },
    poundFields: {
        callback: null,
        type: 6
    },
    tableCurd: {
        callback: null,
        type: 7
    },
    poundSummary: {
        callback: null,
        type: 8
    }
}

const mqttStatus = {
    online: false,
    code: '',
    appOnline: false
}


export const realtimeWeightData = {
    weight: '',
    state: '信号传输异常'
}

export const realtimeDevicesData = {
    devices: []
}

/**
 * @description: 获取机器码对应的数据
 */
export function getMainApplication(code: string) {
    return ajhttp({
        method: 'GET',
        url: `https://${server}/platform/common/getMainApplication`,
        data: {
            code
        },
        header: {
            Authorization: defaultToken
        }
    })
}

export function on(event: MQTTEvent, callback: any) {
    eventBus.off(event, callback)
    eventBus.on(event, callback)
}

export function off(event: MQTTEvent, callback: any) {
    eventBus.off(event, callback)
}

export function connect(appData) {

    mqttStatus.code = appData.code
    mqttStatus.appOnline = appData.online

    uni.showLoading({
        title: '正在连接...',
        mask: true
    })

    try {
        clientIns = mqtt.connect(mqttUrl)
    } catch (e) {
        uni.hideLoading()
        console.log(e)
        uni.showToast({
            icon: 'none',
            title: '连接失败'
        })
        return
    }

    clientIns.on('connect', (e) => {
        console.log('connect', e)
        uni.hideLoading()
        mqttStatus.online = true
        uni.showToast({
            icon: 'none',
            title: '已连接'
        })
        eventBus.emit(MQTTEvent.Connect)

        clientIns.subscribe(topic.response, null, (err) => {
            console.log('subscribe', err)
            if (err) {
                console.log('subscribe err', err)
            }

        });

        clientIns.on("message", (topicId, message) => {
            // message is Buffer
            if (topicId != topic.response) {
                return
            }

            var msgObj = JSON.parse(message.toString())

            if (msgObj.Code != mqttStatus.code) {
                return
            }

            switch (msgObj.Type) {
                case messageType.getCfg.type:
                    if (messageType.getCfg.callback) {
                        messageType.getCfg.callback(msgObj)
                    }
                    break
                case messageType.updateCfg.type:
                    if (messageType.updateCfg.callback) {
                        messageType.updateCfg.callback(msgObj)
                    }
                    break
                case messageType.poundFields.type:
                    if (messageType.poundFields.callback) {
                        messageType.poundFields.callback(msgObj)
                    }
                    break
                case messageType.tableCurd.type:
                    if (messageType.tableCurd.callback) {
                        messageType.tableCurd.callback(msgObj)
                    }
                    break

                case messageType.poundSummary.type:
                    if (messageType.poundSummary.callback) {
                        messageType.poundSummary.callback(msgObj)
                    }
                    break

                case messageType.execCmd.type:
                    if (messageType.execCmd.callback) {
                        messageType.execCmd.callback(msgObj)
                    }
                    if (!messageType.execCmd.silent && msgObj.Success) {
                        uni.showToast({
                            icon: 'none',
                            title: '命令已发送'
                        })
                    }

                default:
                    break
            }

        });

    })

    clientIns.on('disconnect', (e) => {
        console.log('disconnect', e)
        mqttStatus.online = false
        uni.showToast({
            icon: 'none',
            title: '连接已断开'
        })
        eventBus.emit(MQTTEvent.Disconnect)
    })

    clientIns.on('error', (e) => {
        console.log('error', e)
        mqttStatus.online = false
        uni.showToast({
            icon: 'none',
            title: '连接失败'
        })
        eventBus.emit(MQTTEvent.Error)
    })
}

export function updateConfig(data: any, callback: any) {

    messageType.updateCfg.callback = callback
    publish(data, messageType.updateCfg.type)

}

export function getAllConfig(callback: any) {

    messageType.getCfg.callback = callback
    publish(null, messageType.getCfg.type)
}

export function execCmd(cmdKey: cmdKey, cmdParams: any, callback: any, silent: boolean = false) {
    messageType.execCmd.silent = silent
    messageType.execCmd.callback = callback
    publish({
        key: cmdKey,
        params: cmdParams
    }, messageType.execCmd.type)
}

export function getPoundFields(data, callback) {

    messageType.poundFields.callback = callback
    publish(data, messageType.poundFields.type)

}

export function tableCurd(data, callback) {

    messageType.tableCurd.callback = callback
    publish(data, messageType.tableCurd.type)

}

export function poundSummary(data, callback) {

    messageType.poundSummary.callback = callback
    publish(data, messageType.poundSummary.type)

}


function publish(data, type) {
    if (!mqttStatus.online) {
        uni.showToast({
            icon: 'none',
            title: '未连接或已断开'
        })
        return
    }
    clientIns.publish(topic.request, JSON.stringify({
        Code: mqttStatus.code,
        Type: type,
        Body: data
    }))
}

export default mqttStatus